package com.example.mysql.学习笔记.高级.数据库的优化之索引.InnoDB数据存储结构存储;

public class 页之上的区段与碎片区 {
}

/**
 * 为什么要有区
 * B+树的每--层中的页都会形成一个双向链表，
 * 如果是以页为单位来分配存储空间的话，双向链表相邻的两个页之间的物理位置可能离得非常远。
 * 我们介绍B+树索引的适用场景的时候特别提到范围查询只需要定位到最左边的记录和最右边的记录，
 * 然后沿着双向链表一直扫描就可以了，而如果链表中相邻的两个页物理位置离得非常远，就是所谓的随机I/0。
 * 再一次强调，磁盘的速度和内存的速度差了好几个数量级，随机I/0是非常慢的,
 * 所以我们应该尽量让链表中相邻的页的物理位置也相邻,这样进行范围查询的时候才可以使用所谓的顺序I/0。
 * 引入区的概念，一个区就是在物理位置上连续的64个页。
 * 因为InnoDB中的页大小默认是16KB.所以一个区的大小是64* 16KB= 1MB。
 * 在表中数据量大的时候，为某个索引分配空间的时候就不再按照页为单位分配了而是按照区为单位分配，
 * 甚至在表中的数据特别多的时候，可以一次性分配多个连续的区。
 * 虽然可能造成一点点空间的浪费(数据不足以填充满整个区)，
 * 但是从性能角度看，可以消除很多的随机I/0，功大于过 !
 *
 */

/**
 * 为什么要有段?  叶子节点段  非叶子节点段 等
 * 对于范围查询，其实是对B+树叶子节点中的记录进行顺序扫描，而如果不区分叶子节点和非叶子节点,
 * 统统把节点代表的页面放到申请到的区中的话，进行范围扫描的效果就大打折扣了。
 * 所以InnoDB对B+树的叶子节点和非叶子节点进行了区别对待，也就是说叶子节点有自己独有的区,
 * 非叶子节点也有自己独有的区。
 * 存放叶子节点的区的集合就算是一个段( segment)，存放非叶子节点的区的集合也算是一个段。
 * 也就是说一个索引会生成2个段，一个叶子节点段，一个非叶子节点段。
 * 除了索引的叶子节点段和非叶子节点段之外，InnoDB中还有为存储--些特殊的数据而定义的段，比如回滚段。
 * 所以，常见的段有数据段、索引段、回滚段。数据段即为B+树的叶子节点，索弓|段即为B+树的非叶子节点。
 * 在InnoDB存储弓|擎中，对段的管理都是由引擎自身所完成，DBA不能也没有必要对其进行控制。
 * 这从一定程度上简化了DBA对于段的管理。
 * 段其实不对应表空间中某一个连续的物理区域，而是一个逻辑上的概念，
 * 由若千个零散的页面以及--些完整的区组成。
 */

/**
 * 为什么要有碎片区?
 * 默认情况下，一个使用InnoDB存储引擎的表只有一个聚簇索引，一个索引会生成2个段，而段是以区为单位申请存储空间的，
 * 一个区默认占用1M (64 * 16Kb = 1024Kb)存储空间，
 * 所以默认情况下--个只存了几条记录的小表也需要2M的存储空间么?
 * 以后每次添加一个索引都要多申请2M的存储空间么?
 * 这对于存储记录比较少的表简直是天大的浪费。
 * 这个问题的症结在于到现在为止我们介绍的区都是非常纯粹的，
 * 也就是一个区被整个分配给某一个段，或者说区中的所有页面都是为了存储同一个段的数据而存在的，
 * 即使段的数据填不满区中所有的页面，那余下的页面也不能挪作他用。
 * 为了考虑以完整的区为单位分配给某个段对于数据量较小的表太浪费存储空间的这种情况，
 * InnoDB提出了一个碎片(fragment)区的概念。
 * 在一个碎片区中，并不是所有的页都是为了存储同一个段的数据而存在的，
 * 而是碎片区中的页可以用于不同的目的，比如有些页用于段A,有些页用于段B,有些页甚至哪个段都不属于。
 * 碎片区直属于表空间，并不属于任何一个段。
 *
 * 所以此后为某个段分配存储空间的策略是这样的:
 * ●在刚开始向表中插入数据的时候，段是从某个碎片区以单个页面为单位来分配存储空间的。
 * ●当某个段已经占用了"""32"""个碎片区页面之后，就会申请以完整的区为单位来分配存储空间。
 *  所以现在段不能仅定义为是某些区的集合，更精确的应该是某些零散的页面以及一些完整的区的集合。
 *
 */

/**
 * 区的分类
 * 区大体上可以分为4种类型:
 * ●空闲的区(FREE) :现在还没有用到这个区中的任何页面。
 * ●有剩余空间的碎片区(FREE. FRAG) :表示碎片区中还有可用的页面。
 * ●没有剩余空间的碎片区(FULL. FRAG) :表示碎片区中的所有页面都被使用，没有空闲页面。
 * ●附属于某个段的区(FSEG) :每一个索弓|都可以分为叶子节点段和非叶子节点段。
 * 处于FREE、FREE_ FRAG 以及FULL_ FRAG这三种状态的区都是独立的，直属于表空间。
 * 而处于FSEG状态的区是附属于某个段的。
 */